package kz.pompei.ifacer.visio;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import kz.pompei.ifacer.grot.acts.Act;
import kz.pompei.ifacer.grot.acts.ChangeFieldsAct;
import kz.pompei.ifacer.model.CursorKind;
import kz.pompei.ifacer.model.widgets.WidgetRect;

public class PaintUtil {
  
  public static final int BOTTOM_OFFSET = 4;
  public static final int MARKER_OFFSET = 4;
  
  public static final int BORDER_WIDTH = 3;
  public static final int CORNER_SIZE = 7;
  
  public static void drawSelectionRect(Graphics2D g, int x, int y, int width, int height) {
    Graphics2D g2 = (Graphics2D)g.create();
    g2.setColor(Color.BLACK);
    
    float dash1[] = { 10.0f, 3f, 4f, 3f };
    BasicStroke dashed = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f,
        dash1, 0.0f);
    
    g2.setStroke(dashed);
    
    g2.drawRect(x - 1, y - 1, width + 2, height + 2);
    //g2.draw(new RoundRectangle2D.Double(f.x, f.y, f.width, f.height, 10, 10));
    
    g2.dispose();
    
  }
  
  public static void drawSelectionRect(Graphics2D g, Rectangle r) {
    drawSelectionRect(g, r.x, r.y, r.width, r.height);
  }
  
  public static Act resize(int dx, int dy, CursorKind borderCursor, WidgetRect from, WidgetRect to) {
    switch (borderCursor) {
    case RESIZE_N: {
      to.y = from.y + dy;
      to.height = from.height - dy;
      return new ChangeFieldsAct(from.uuid, "y", to.y, "height", to.height);
    }
    
    case RESIZE_E: {
      to.width = from.width + dx;
      return new ChangeFieldsAct(from.uuid, "width", to.width);
    }
    
    case RESIZE_S: {
      to.height = from.height + dy;
      return new ChangeFieldsAct(from.uuid, "height", to.height);
    }
    
    case RESIZE_W: {
      to.x = from.x + dx;
      to.width = from.width - dx;
      return new ChangeFieldsAct(from.uuid, "x", to.x, "width", to.width);
    }
    
    case RESIZE_NE: {
      to.y = from.y + dy;
      to.height = from.height - dy;
      to.width = from.width + dx;
      return new ChangeFieldsAct(from.uuid, "y", to.y, "height", to.height, "width", to.width);
    }
    
    case RESIZE_NW: {
      to.y = from.y + dy;
      to.height = from.height - dy;
      to.x = from.x + dx;
      to.width = from.width - dx;
      return new ChangeFieldsAct(from.uuid, "y", to.y, "height", to.height, "x", to.x, "width",
          to.width);
    }
    
    case RESIZE_SE: {
      to.height = from.height + dy;
      to.width = from.width + dx;
      return new ChangeFieldsAct(from.uuid, "height", to.height, "width", to.width);
    }
    
    case RESIZE_SW: {
      to.height = from.height + dy;
      to.x = from.x + dx;
      to.width = from.width - dx;
      return new ChangeFieldsAct(from.uuid, "height", to.height, "x", to.x, "width", to.width);
    }
    
    case MOVE: {
      to.x = from.x + dx;
      to.y = from.y + dy;
      return new ChangeFieldsAct(from.uuid, "x", to.x, "y", to.y);
    }
    
    default:
      throw new IllegalStateException("Unknown border cursor " + borderCursor);
    }
  }
  
  public static void drawOverRect(Graphics2D g, Rectangle r) {
    Graphics2D g2 = (Graphics2D)g.create();
    g2.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL));
    g2.setColor(Color.BLACK);
    g2.drawRect(r.x + 1, r.y + 1, r.width - 1, r.height - 1);
    g2.dispose();
  }
  
  public static void drawRectVert(Graphics2D g, int x, int y, int width, int height,
      Color topColor, Color bottomColor) {
    for (int i = 0; i < height; i++) {
      g.setColor(middleColor((float)i / (float)height, topColor, bottomColor));
      g.drawLine(x, y + i, x + width, y + i);
    }
  }
  
  public static Color middleColor(float percent, Color from, Color to) {
    float fromR = from.getRed();
    float fromG = from.getGreen();
    float fromB = from.getBlue();
    float fromA = from.getAlpha();
    
    float toR = to.getRed();
    float toG = to.getGreen();
    float toB = to.getBlue();
    float toA = to.getAlpha();
    
    int R = (int)(fromR + (toR - fromR) * percent + 0.5);
    int G = (int)(fromG + (toG - fromR) * percent + 0.5);
    int B = (int)(fromB + (toB - fromR) * percent + 0.5);
    int A = (int)(fromA + (toA - fromR) * percent + 0.5);
    
    if (R > 255) R = 255;
    if (G > 255) G = 255;
    if (B > 255) B = 255;
    if (A > 255) A = 255;
    
    if (R < 0) R = 0;
    if (G < 0) G = 0;
    if (B < 0) B = 0;
    if (A < 0) A = 0;
    
    return new Color(R, G, B, A);
  }
}
